package com.jwater.gateway.common;

import com.jwater.gateway.service.CacheService;
import jwater.org.springframework.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.web.server.ServerWebExchange;

import java.net.URI;
import java.util.function.Predicate;

/**
 * @description:
 * @author: jnner
 * @createDate: 2021/3/27
 * @version: 1.0
 */
public class CommonPredicateFactory extends AbstractRoutePredicateFactory<CommonPredicateFactory.Config> {
    protected static final Logger LOGGER = LoggerFactory.getLogger(CommonPredicateFactory.class);

    @Autowired
    private CacheService cacheService;

    public CommonPredicateFactory(Class<Config> configClass) {
        super(configClass);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new CommonPredicate();
    }

    public class CommonPredicate implements Predicate<ServerWebExchange> {
        @Override
        public boolean test(ServerWebExchange exchange) {
            URI srcURI = exchange.getRequest().getURI();
            String path = srcURI.getPath();
            LOGGER.info("path:" + path);
            // websocket
            String upgrade = exchange.getRequest().getHeaders().getUpgrade();
            if ("websocket".equalsIgnoreCase(upgrade)) {
                String destWsUrl = cacheService.getWsMappingByPrefix(path);
                if (destWsUrl == null) {
                    return false;
                }
                destWsUrl = wrapUrl(destWsUrl, srcURI);
                LOGGER.info("destWsUrl:" + destWsUrl);
                exchange.getAttributes().put("_destWsUrl_", destWsUrl);
                return true;
            } else {
                String destUrl = cacheService.getMappingByPrefix(path);
                if (destUrl == null) {
                    return false;
                }
                destUrl = wrapUrl(destUrl, srcURI);
                LOGGER.info("destUrl:" + destUrl);
                exchange.getAttributes().put("_destUrl_", destUrl);
                return true;
            }
        }

        private String wrapUrl(String destUrl, URI srcURI) {
            try {
                String query = srcURI.toURL().getQuery();
                if (!StringUtils.isEmpty(query)) {
                    return destUrl + "?" + query;
                }
            } catch (Exception e) {
                LOGGER.error(e.toString(), e);
            }
            return destUrl;
        }
    }


    public static class Config {
    }
}
